﻿namespace Digitalmes.Application.Common.Behaviours;

/// <summary>
/// MediatR 性能记录管道。
/// </summary>
/// <typeparam name="TRequest"></typeparam>
/// <typeparam name="TResponse"></typeparam>
/// <remarks>会对事件执行时长超过 500ms 的请求进行日志记录。</remarks>
public sealed class PerformanceBehaviour<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : notnull
{
    private readonly Stopwatch _timer;

    private readonly ICurrentUser? _user;
    private readonly ILogger<TRequest> _logger;

    public PerformanceBehaviour(ILogger<TRequest> logger, [MaybeNull] ICurrentUser? user = null)
    {
        _user = user;
        _logger = logger;

        _timer = new Stopwatch();
    }

    public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
    {
        _timer.Start();

        var response = await next();

        _timer.Stop();

        var elapsedMilliseconds = _timer.ElapsedMilliseconds;
        if (elapsedMilliseconds > 1_000)
        {
            var requestName = typeof(TRequest).Name;
            var userId = _user?.UserId?.ToString() ?? string.Empty;
            var userName = _user?.UserName ?? string.Empty;

            _logger.LogWarning("Pipeline Long Running Request: {Name} ({ElapsedMilliseconds} milliseconds) {@UserId} {@UserName} {@Request}",
                requestName, elapsedMilliseconds, userId, userName, request);
        }

        return response;
    }
}
